<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Module 9p_server</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
</head>
<body bgcolor="white">
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
<hr>

<h1>Module 9p_server</h1>
<ul class="index"><li><a href="#description">Description</a></li><li><a href="#types">Data Types</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>.


<h2><a name="description">Description</a></h2>

<p>Each Erlang on Xen node has a running local 9p server. The 9p server serves a series of
synthetic and/or not-so-synthetic files organized into a two-level hierarchy.
Explanations below assumes the following sample hierarchy:</p>

<pre>
	/
	/boot
	/boot/local.map
	/boot/start.boot
	/stdlib
	/stdlib/dict.ling
	/proc
	/proc/1
	/proc/2
</pre>
	
<p>The first level names (<code>/boot</code>, <code>/stdlib</code>, and <code>/proc</code>) are <em>always</em>
directories. Such directories are called 'export' directories. The second level
names, e.g. <code>/proc/1</code>, are <em>always</em> files. Thus the root directory <code>/</code> cannot
contain files and export directories cannot contain other directories. These
limitations of the 9p server hierarchy are not carried over to applications
consuming the exported tree as the exported names can be mounted at arbitrary
locations.</p>

<h3>9p protocol flavours</h3>

<p>The 9p server supports two 9p protocol flavours: 9p2000.u and 9p2000.e. The
former is usually for connections originating from 9pfs driver included into the
standard Linux kernel. The latter is typically for connections from other Erlang
on Xen nodes.</p>

<p>9p2000.L, the Linux flavour of the 9p protocol, is not supported by the 9p
server. The 9p client in its turn can originate 9p2000.L connections to
Linux-based servers.</p>

<h3>Custom export modules</h3>

<p>Each export directory is associated with a callback module. The 9p server
invokes the callback module when an operation is requested on the directory or
any file it contains. A single callback module may be responsible for multiple
directories. For example, both <code>/boot</code> and <code>/stdlib</code> are associated with
<code>embedded_export</code> module. Callbacks receive an additional parameter that allow
them to distinguish between directories in such cases.</p>

<p>9p server tries to collect and provide as much information as possible by itself
without asking the callback module. For example, all walk operations are mostly
handled by 9p server. The callback module may be asked to verify
permissions in such cases.</p>

<p>Each callback module implements a predefined set of functions. If certain
function is not exported by the module, a default implementation is used
instead.</p>

<p>All calls receive Conn and ModConf parameters. Conn is an opaque structure that
can be queried using <a href="9p_info.html">9p_info</a> functions. ModConf parameter
contains the callback module configuration. It can be used to distinguish
between directories when one callback module serves several of them.</p>

<p>Names and aliases can be used interchangably. Passing an alias instead of a name
is often faster.</p>

<p>Predefined functions of an export module:</p>

<pre>
	top_granted(User, Conn, ModConf) -&gt; true | false
	file_granted(Name, User, Conn, ModConf) -&gt; true | false
	list_dir(Conn, ModConf) -&gt; Files
	find(Name, Conn, ModConf) -&gt; {found,Alias} | false
	create(Name, Conn, ModConf) -&gt; true | false
	remove(Name, Conn, ModConf) -&gt; true | false
	rename(Name, Conn, ModConf) -&gt; true | false
	read(Name, Offset, Count, Conn, ModConf) -&gt; {cache,Data} | Data
	write(Name, Offset, Data, Conn, ModConf) -&gt; Count
	truncate(Name, Size, Conn, ModConf) -&gt; true
	top_stat(Conn, ModConf) -&gt; #stat{}
	file_stat(Name, Conn, ModConf) -&gt; #stat{}
</pre>

<p>Detailed description of predefined functions of a callback module follow.</p>

<pre>
	top_granted(User, Conn, ModConf) -&gt; true | false
</pre>

<p>Authorizes attach/walk operation for the entire export directory.
<em>User</em> is a user name or a <code>{UserName,UserId}</code> tuple taken from attach
parameters. <em>User</em> is set to <code>undefined</code> for walk operations. Defaults to
<code>true</code>.</p>

<pre>
	file_granted(Name, User, Conn, ModConf) -&gt; true | false
</pre>

<p>Authorizes attach/walk operation for a named file in the exported directory.
<em>User</em> is a user name or a <code>{UserName,UserId}</code> tuple taken from attach
parameters. <em>User</em> is set to <code>undefined</code> for walk operations. Defaults to
<code>true</code>.</p>

<pre>
	list_dir(Conn, ModConf) -&gt; Files
</pre>

<p>Returns the list of <code>{Name,Alias}</code> tuples for all files in the directory. Names
are represented as binaries. No default.</p>

<pre>
	find(Name, Conn, ModConf) -&gt; {found,Alias} | false
</pre>

<p>Checks if the named file exists and returns its alias. The alias may be the same
as Name. No default.</p>

<pre>
	create(Name, Conn, ModConf) -&gt; true | false
</pre>

<p>Creates the named file. Returns <code>true</code> if successful, and <code>false</code> otherwise.
Defaults to <code>false</code>.</p>

<pre>
	remove(Name, Conn, ModConf) -&gt; true | false
</pre>

<p>Remove the named file. Returns <code>true</code> if successful. Defaults to <code>false</code>. Note
that it is not possible to 'remove' the exported directory.</p>

<pre>
	rename(Name, NewName, Conn, ModConf) -&gt; true | false
</pre>

<p>Renames the file to NewName. Returns <code>true</code> if successful. Defaults to
<code>false</code>.</p>

<pre>
	read(Name, Offset, Count, Conn, ModConf) -&gt; {cache,Data} | Data
</pre>

<p>Reads (maximum) <em>Count</em> bytes from the named file starting at
<em>Offset</em> and returns them as a binary. Note that the size of
<em>Data</em> may be less than <em>Count</em>. Defaults to &lt;&lt;&gt;&gt;.</p>

<p><code>{cache,Data}</code> return value contains the whole contents of the file. The caller
may save the value and serve this and any subsequent read requests by slicing
the cached value. If <code>Offset</code> is 0, then <code>read()</code> should be queried even if the
cached contents is available. This creates a chance for refreshing the cached
file contents. The cached data may be either a binary or a list of binaries. In
the latter case, when slicing the cached value the boundaries of binaries should
not be crossed. Such behaviour is needed for serving data represented as
records, for example, when reading directories.</p>

<pre>
	write(Name, Offset, Data, Conn, ModConf) -&gt; Count
</pre>

<p>Write <em>Data</em> to the named file starting at <em>Offset</em>. Returns number of bytes
actually written. Defaults to <code>0</code>.</p>

<pre>
	truncate(Name, Size, Conn, ModConf) -&gt; true
</pre>

<p>Truncate the size of the named file to <em>Size</em>.</p>

<pre>
	top_stat(Name, Conn, ModConf) -&gt; #stat{}
</pre>

<p>Fills in the stat structure with information about the export directory itself.
The only field that must be set is 'name'. No default. See <a href="#file_stat-3"><code>file_stat/3</code></a>.</p>

<pre>
	file_stat(Name, Conn, ModConf) -&gt; #stat{}
</pre>

<p>Fills in the stat structure with information about the file. Fields 'name' and
'length' must be set. No default.</p>

<p>The layout of the stat record is as follows:</p>

<pre>
-record(stat, {ver =e,    %% 9P2000.e or 9P2000.u
               type =0,    %% Plan 9?
               dev =0,    %% Plan 9?
               qid,
               mode,
               atime,
               mtime,
               length,
               name,
               uid = &lt;&lt;&gt;&gt;,
               gid = &lt;&lt;&gt;&gt;,
               muid = &lt;&lt;&gt;&gt;,
               ext = &lt;&lt;&gt;&gt;,
               num_uid =0,
               num_gid =0,
               num_muid =0}).
</pre>


<h2><a name="types">Data Types</a></h2>

<h3 class="typedecl"><a name="type-mod_conf">mod_conf()</a></h3>
<p><tt>mod_conf() = any()</tt></p>


<h3 class="typedecl"><a name="type-name">name()</a></h3>
<p><tt>name() = binary()</tt></p>


<h2><a name="index">Function Index</a></h2>
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#add_export-3">add_export/3</a></td><td>Adds an exported directory to the 9p server.</td></tr>
<tr><td valign="top"><a href="#add_listener-3">add_listener/3</a></td><td>Add a 9p server listener.</td></tr>
<tr><td valign="top"><a href="#add_listener-4">add_listener/4</a></td><td>Add a 9p server listener.</td></tr>
<tr><td valign="top"><a href="#remove_export-1">remove_export/1</a></td><td>Stops exporting the directory.</td></tr>
<tr><td valign="top"><a href="#remove_listener-1">remove_listener/1</a></td><td>Remove the listener identified by <code>Id</code>.</td></tr>
<tr><td valign="top"><a href="#start_link-0">start_link/0</a></td><td>Starts the '9p_server' and sets up listeners.</td></tr>
<tr><td valign="top"><a href="#trace_messages-0">trace_messages/0</a></td><td>Retrieve the current trace messages flag.</td></tr>
<tr><td valign="top"><a href="#trace_messages-1">trace_messages/1</a></td><td>Starts/stops message tracing.</td></tr>
</table>

<h2><a name="functions">Function Details</a></h2>

<h3 class="function"><a name="add_export-3">add_export/3</a></h3>
<div class="spec">
<p><tt>add_export(Name, ExpMod, ModConf) -&gt; ok | {error, Error}</tt>
<ul class="definitions"><li><tt>Name = <a href="#type-name">name()</a></tt></li><li><tt>ExpMod = module()</tt></li><li><tt>ModConf = <a href="#type-mod_conf">mod_conf()</a></tt></li><li><tt>Error = any()</tt></li></ul></p>
</div><p>Adds an exported directory to the 9p server. <code>Name</code> is the name of the
  directory without the leading slash. For example, a directory named
  <code>&lt;&lt;"proc"&gt;&gt;</code> is exported as <code>/proc</code> by the server.</p>

<h3 class="function"><a name="add_listener-3">add_listener/3</a></h3>
<div class="spec">
<p><tt>add_listener(Id, TransMod, TransConf) -&gt; ok | {error, Error}</tt>
<ul class="definitions"><li><tt>Id = any()</tt></li><li><tt>TransMod = module()</tt></li><li><tt>TransConf = <a href="#type-mod_conf">mod_conf()</a></tt></li><li><tt>Error = any()</tt></li></ul></p>
</div><p>Add a 9p server listener. <code>TransMod</code> and <code>TranConf</code> specify the transport
  endpoint. <code>Id</code> is an arbitrary listener identifier.</p>

<h3 class="function"><a name="add_listener-4">add_listener/4</a></h3>
<div class="spec">
<p><tt>add_listener(Id, TransMod, TransConf, NumAcc) -&gt; ok | {error, Error}</tt>
<ul class="definitions"><li><tt>Id = any()</tt></li><li><tt>TransMod = module()</tt></li><li><tt>TransConf = <a href="#type-mod_conf">mod_conf()</a></tt></li><li><tt>NumAcc = integer()</tt></li><li><tt>Error = any()</tt></li></ul></p>
</div><p>Add a 9p server listener. <code>TransMod</code> and <code>TranConf</code> specify the
  transport endpoint. <code>Id</code> is an arbitrary listener identifier. <code>NumAcc</code> is
  the number of acceptor processes simultaneously waiting for incoming
  connections on the endpoint.</p>

<h3 class="function"><a name="remove_export-1">remove_export/1</a></h3>
<div class="spec">
<p><tt>remove_export(Name) -&gt; ok</tt>
<ul class="definitions"><li><tt>Name = <a href="#type-name">name()</a></tt></li></ul></p>
</div><p>Stops exporting the directory.</p>

<h3 class="function"><a name="remove_listener-1">remove_listener/1</a></h3>
<div class="spec">
<p><tt>remove_listener(Id) -&gt; ok</tt>
<ul class="definitions"><li><tt>Id = any()</tt></li></ul></p>
</div><p>Remove the listener identified by <code>Id</code>.</p>

<h3 class="function"><a name="start_link-0">start_link/0</a></h3>
<div class="spec">
<p><tt>start_link() -&gt; {ok, pid()}</tt><br></p>
</div><p>Starts the '9p_server' and sets up listeners.</p>

<h3 class="function"><a name="trace_messages-0">trace_messages/0</a></h3>
<div class="spec">
<p><tt>trace_messages() -&gt; boolean()</tt><br></p>
</div><p>Retrieve the current trace messages flag.</p>

<h3 class="function"><a name="trace_messages-1">trace_messages/1</a></h3>
<div class="spec">
<p><tt>trace_messages(Flag::boolean()) -&gt; boolean()</tt><br></p>
</div><p>Starts/stops message tracing. The flag affect only new connections.</p>
<hr>

<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
<p><i>Generated by EDoc, Aug 9 2013, 01:28:48.</i></p>
</body>
</html>
